package com.farm.wcp.controller;

import java.io.UnsupportedEncodingException;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.farm.authority.FarmAuthorityService;
import com.farm.authority.service.UserServiceInter;
import com.farm.core.auth.domain.LoginUser;
import com.farm.core.auth.exception.CheckCodeErrorException;
import com.farm.core.auth.exception.LoginUserNoAuditException;
import com.farm.core.auth.exception.LoginUserNoExistException;
import com.farm.core.page.ViewMode;
import com.farm.file.FarmFileServiceInter;
import com.farm.parameter.FarmParameterService;
import com.farm.wcp.util.CheckCodeUtil;
import com.farm.wcp.util.PasswordChecks;
import com.farm.wcp.util.RemoteGoUrls;
import com.farm.wcp.util.ThemesUtil;
import com.farm.wcp.util.UserInfoForcedModifications;
import com.farm.web.WebUtils;

@RequestMapping("/login")
@Controller
public class LoginWebController extends WebUtils {
	private final static Logger log = Logger.getLogger(LoginWebController.class);
	@Resource
	private UserServiceInter userServiceImpl;
	@Resource
	private FarmFileServiceInter farmFileServiceImpl;

	/**
	 * 进入WCP站内登录页面
	 * 
	 * @param session
	 * @param outuserid 外部用户，有外部用户时表示要绑定到外部用户
	 * @param type      当前登陆类型，密码、微信、随机登陆等...
	 * @param intent    子系统的用户操作类型（登陆login或登出logout）
	 * @param statecode 客户端参数（只在已经登陆的情况下有效，用户未登陆再登陆后不会传此参数）
	 * @param request
	 * @return
	 */
	@SuppressWarnings("deprecation")
	@RequestMapping("/PubLogin")
	public ModelAndView pubLogin(HttpSession session, String outuserid, String intent, String statecode,
			HttpServletRequest request) {
		ViewMode mode = ViewMode.getInstance();
		try {
			// 当前用户
			LoginUser user = getCurrentUser(session);
			if (user != null) {
				mode.putAttr("user", user);
				if ("login".equals(intent)) {
					// 直接登陆
					String goUrl = RemoteGoUrls.getGoUrl(session);
					// 本地登陆
					return ViewMode.getInstance().returnRedirectUrl(goUrl);
				}
			}
			mode.putAttr("type", "PASSWORD");
			// ------------------------------------------------------------------------
			initLoginSalt(session, request);
			return mode.returnModelAndView(ThemesUtil.getThemePage("home-login", request));
		} catch (Exception e) {
			return ViewMode.getInstance().setError(e.getMessage(), e)
					.returnModelAndView(ThemesUtil.getThemePath() + "/simple-500");
		}
	}


	/**
	 * 进入默认登录页面（可在配置文件wcpWebConfig.xml中config.login.default.url配置默认页面为default:
	 * login/PubLogin）
	 * 
	 * @param session
	 * @return
	 */
	@RequestMapping("/webPage")
	public ModelAndView login(HttpSession session, HttpServletRequest request) {
		// 将登录前的页面地址存入session中，为了登录后回到该页面中
		String url = request.getHeader("Referer");
		session.setAttribute(FarmParameterService.getInstance().getParameter("farm.constant.session.key.from.url"),
				url);
		try {
			String defultLoginUrl = FarmParameterService.getInstance().getParameter("config.login.default.url");
			if (!defultLoginUrl.toUpperCase().equals("DEFAULT")) {
				return ViewMode.getInstance().returnRedirectUrl(defultLoginUrl);
			}
		} catch (Exception e) {
			log.error(e);
		}
		return ViewMode.getInstance().returnRedirectOnlyUrl("/login/PubLogin.html");
	}

	/**
	 * 验证验证码并且获取用户登录名
	 * 
	 * @param checkcode 验证码
	 * @param name      登录名/手机号/邮箱
	 * @param session
	 * @return
	 * @throws CheckCodeErrorException
	 */
	private String findUserLoginName(String name, HttpSession session) {
		return name;
	}

	/**
	 * 处理登录状态结果
	 * 
	 * @param state
	 */
	private void CheckCodeHandle(String loginname, boolean state, String ip) {
		if (state) {
			CheckCodeUtil.setLoginSuccess(loginname);
		} else {
			CheckCodeUtil.addLoginErrorNum(loginname);
			PasswordChecks.addFail(loginname, ip);
		}
	}

	/**
	 * 提交登录请求
	 * 
	 * @param checkcode
	 * @param outuserid 外部用户，有外部用户时表示要绑定到外部用户
	 * @param name      loginname
	 * @param password
	 * @param request
	 * @param session
	 * @return
	 */
	@SuppressWarnings("deprecation")
	@RequestMapping("/websubmit")
	public ModelAndView webLoginCommit(String checkcode, String sck, String name, String password,
			HttpServletRequest request, HttpSession session) {
		ViewMode view = ViewMode.getInstance();
		try {
			// 是否启用登录验证码
			if (!CheckCodeUtil.isCheckCodeAble(name, checkcode, session)) {
				// throw new CheckCodeErrorException("验证码未通过");
				// 该方法会自动抛出异常
			}
			String loginname = findUserLoginName(name, session);
			PasswordChecks.check(name, getCurrentIp(request));
			if (FarmAuthorityService.getInstance().isLegality(loginname, password, getLoginSalt(session))) {
				// 登录成功
				// 注册session
				Map<String, String> loginParas = FarmAuthorityService.loginIntoSession(session, getCurrentIp(request),
						loginname, "登录页");
				sendFirstMessageToUser(loginParas,
						FarmParameterService.getInstance().getParameter("config.sys.firstlogin.message"));
				String goUrl = RemoteGoUrls.getGoUrl(session);
				CheckCodeHandle(name, true, getCurrentIp(request));
				// 判断是否要修改密码
				if (UserInfoForcedModifications.isForcedModificationPassword(getCurrentUser(session), session)) {
					// 跳轉到密碼修改頁面
					return ViewMode.getInstance()
							.returnRedirectUrl("/" + UserInfoForcedModifications.getPasswordUpdateUrl());
				}
				return ViewMode.getInstance().returnRedirectUrl(goUrl);
			} else {
				// 登录失败
				log.info("密码错误");
				CheckCodeHandle(name, false, getCurrentIp(request));
				if ((getLoginSalt(session) != null && (!getLoginSalt(session).equals(sck) || StringUtils.isBlank(sck)))
						|| (StringUtils.isNotBlank(sck) && getLoginSalt(session) == null)) {
					log.info("登陆凭证过期");
					view.setError("登陆凭证过期,请重新启动浏览器后再次登陆", null);
				} else {
					log.info("密码错误");
					view.setError("账户或密码错误", null);
				}
				initLoginSalt(session, request);
				return view.putAttr("loginname", name)
						.returnModelAndView(ThemesUtil.getThemePage("home-login", request));
			}
		} catch (LoginUserNoExistException e) {
			log.info("当前用户不存在");
			CheckCodeHandle(name, false, getCurrentIp(request));
			initLoginSalt(session, request);
			return view.putAttr("loginname", name).setError("登陆名或密码错误", null)
					.returnModelAndView(ThemesUtil.getThemePage("home-login", request));
		} catch (CheckCodeErrorException e) {
			initLoginSalt(session, request);
			return view.putAttr("loginname", name).setError("验证码错误", null)
					.returnModelAndView(ThemesUtil.getThemePage("home-login", request));
		} catch (LoginUserNoAuditException e) {
			return view.putAttr("MESSAGE", "当前用户已经注册成功，正等待管理员审核!")
					.returnModelAndView(ThemesUtil.getThemePath() + "/simple-message");
		} catch (Exception e) {
			initLoginSalt(session, request);
			return view.putAttr("loginname", name).setError(e.getMessage(), null)
					.returnModelAndView(ThemesUtil.getThemePage("home-login", request));
		}
	}

	/**
	 * 返回登陸前頁面
	 * 
	 * @param request
	 * @param session
	 * @return
	 */
	@SuppressWarnings("deprecation")
	@RequestMapping("/back")
	public ModelAndView goBack(HttpServletRequest request, HttpSession session) {
		try {
			String goUrl = RemoteGoUrls.getGoUrl(session);
			// 本地登陆
			return ViewMode.getInstance().returnRedirectUrl(goUrl);
		} catch (Exception e) {
			return ViewMode.getInstance().setError(e.getMessage(), e)
					.returnModelAndView(ThemesUtil.getThemePath() + "/simple-500");
		}
	}

	/**
	 * 发送第一个系统消息给用户
	 * 
	 * @param loginParas loginIntoSession方法的返回值
	 * @param message    发送的消息内容
	 */
	private void sendFirstMessageToUser(Map<String, String> loginParas, String message) {
		if (loginParas.get("lastLoginTime") == null || loginParas.get("lastLoginTime").isEmpty()) {
			// String firstLoginTipmessage = null;
			// try {
			// firstLoginTipmessage = message;
			// } catch (Exception e) {
			// firstLoginTipmessage = "欢迎登录系统！";
			// }
			// Message messageMaster = new Message(TYPE_KEY.user_login);
			// messageMaster.initTitle();
			// messageMaster.initText().setString(firstLoginTipmessage);
			// usermessageServiceImpl.sendMessage(messageMaster,
			// loginParas.get("UserId"));
		}
	}

	/**
	 * 可被外部类访问调用（如单点登陆的注销）所以只负责用户注销，不要写入其它逻辑
	 * 
	 * @param session
	 */
	public static void doUserlogout(HttpSession session) {
		logoutUser(session);
		session.invalidate();
	}

	@SuppressWarnings("deprecation")
	@RequestMapping("/webout")
	public ModelAndView weblogOut(String name, HttpServletRequest request, HttpSession session) {
		try {
			logoutUser(session);
			String logoutPlusUrl = FarmParameterService.getInstance().getParameter("config.logout.plus.url");
			if (!logoutPlusUrl.toUpperCase().equals("NONE")) {
				return ViewMode.getInstance().returnRedirectUrl(logoutPlusUrl);
			}
			return ViewMode.getInstance()
					.returnRedirectUrl("/" + WebUtils.getDefaultIndexPage(FarmParameterService.getInstance()));
		} catch (Exception e) {
			return ViewMode.getInstance().setError(e.getMessage(), e)
					.returnModelAndView(ThemesUtil.getThemePath() + "/error");
		}
	}

	@RequestMapping("/out")
	public ModelAndView logOut(String name, HttpServletRequest request, HttpSession session)
			throws UnsupportedEncodingException {
		logoutUser(session);
		return ViewMode.getInstance().returnRedirectUrl("/login/webPage.html");
	}

	/**
	 * 前端请求判断是否需要验证码
	 * 
	 * @param session
	 * @return
	 */
	@RequestMapping("/PubRequireCCode")
	@ResponseBody
	public Map<String, Object> PubRequireCCode(String loginname, HttpSession session) {
		boolean isRequire = CheckCodeUtil.isRequireCheckCode(loginname, session);
		return ViewMode.getInstance().putAttr("require", isRequire).returnObjMode();
	}
}
